import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Random;

public class Process {

	public static int name;
	public static int lamportTimestamp = 0;
	public static int[] vectorTimestamp;
	public static int money = 10000;
	public static int widget = 1000;
	private static Random rand = new Random(name*20);
	public static boolean snapshotInProgress = false;
	public static boolean initiatedSnapshot = false;
	public static Hashtable<Integer, ArrayList<NormalMessage>> receivedMessages = new Hashtable<>();

	public static void main(String[] args) throws IOException, InterruptedException {
		if (args.length != 2) {
			System.out.println("Incorrect arguments: Name");
			System.exit(0);
		}
		name = Integer.parseInt(args[0]);
		ProcessManager.numProcess = Integer.parseInt(args[1]);
		vectorTimestamp = new int[ProcessManager.numProcess];
		int port = ProcessManager.ports[name];
		new Listener(name, port);
		new RoutineWork(name, 1000);
		while (true) {
			int x = rand.nextInt(10) + 1;
			if (x % 2 == 0) {
				sendMessage();
			}
			Thread.sleep(2500);
		}
	}

	public static void snapshot(int snapshotName) {
		Process.snapshotInProgress = true;
		Process.initiatedSnapshot = true;
		String str = "id" + Process.name + " : " + "snapshot" + snapshotName
				+ " : " + "logical " + Process.lamportTimestamp 
				+ " : vector " + printVector(Process.vectorTimestamp) 
				+ " : money " + Process.money + " widget " + Process.widget + "\n";
		Process.writeToFile(str);
		MarkerMessage markerMsg = new MarkerMessage(snapshotName);
		markerMsg.setSenderProcess(name);
		markerMsg.setReceipientsToAllOthers();
		// turns on channels
		for (int i = 0; i < ProcessManager.numProcess; i++) {
			if (i != Process.name) {
				Process.receivedMessages.put(new Integer(i),
						new ArrayList<NormalMessage>());
			}
		}
		new Sender(markerMsg);
	}

	public static void writeToFile(String str) {

		File file = new File("files/Process" + name + ".txt");
		try {
			if (!file.exists()) {
				file.createNewFile();
			}
			FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
			BufferedWriter bw = new BufferedWriter(fw);
			bw.write(str);
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static String printVector(int[] vector) {
		String ret = "[";
		for (int i = 0; i < vector.length - 1; i++) {
			ret += vector[i] + ",";
		}
		ret += vector[vector.length - 1];
		ret += "]";
		return ret;
	}

	private static void sendMessage() {
		int sendMoney = 0;
		int sendWidget = 0;
		int[] r = new int[1];
		r[0] = (rand.nextInt(ProcessManager.numProcess));
		if (r[0] != name) {
			lamportTimestamp++;
			vectorTimestamp[name]++;
			NormalMessage msg = new NormalMessage();
			msg.setSenderProcess(name);
			msg.setLamportTimestamp(lamportTimestamp);
			msg.setVectorTimestamp(vectorTimestamp);
			sendMoney = rand.nextInt(10);
			sendWidget = rand.nextInt(10);
			msg.setMoney(sendMoney);
			msg.setWidget(sendWidget);
			money -= sendMoney;
			widget -= sendWidget;
			
//			System.out.println("Process " + name + " sending " + sendMoney + " money " + sendWidget + " widget");
//			System.out.println("Process " + name + " is left with " + money + " money " + widget + " widget");
			
//			System.out.println("Sending message to " + r[0] + "...");
//			System.out.println("Send Timestamp: " + lamportTimestamp);
//			System.out.println("Send Vector Timestamp: " + vectorTimestamp[0] +
//			" " +
//			vectorTimestamp[1] + " " + vectorTimestamp[2] + " " +
//			vectorTimestamp[3]);
//			System.out.println();
			msg.setReceipients(r);
			new Sender(msg);
		}
	}
}
